import axios from 'axios';

// 服务器地址列表 - 按优先级排序
const SERVER_URLS = [
  'http://10.0.2.2:3000',      // Android模拟器专用IP
  'http://localhost:3000',      // 本地开发
  'http://127.0.0.1:3000',     // 本地回环
  'http://192.168.192.147:3000', // 你的本机IP
];

// 测试服务器连接
async function testServerConnection(url: string): Promise<boolean> {
  try {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 5000);
    
    const response = await fetch(`${url}/sow`, { 
      method: 'GET',
      signal: controller.signal
    });
    
    clearTimeout(timeoutId);
    return response.ok;
  } catch (error) {
    console.log(`❌ 服务器 ${url} 连接失败:`, error);
    return false;
  }
}

// 获取可用的服务器地址
async function getWorkingServer(): Promise<string> {
  for (const url of SERVER_URLS) {
    console.log(`🔍 测试服务器: ${url}`);
    if (await testServerConnection(url)) {
      console.log(`✅ 找到可用服务器: ${url}`);
      return url;
    }
  }
  throw new Error('所有服务器都无法连接');
}

// 上传配置
const UPLOAD_CONFIG = {
  CHUNK_SIZE: 1024 * 1024, // 1MB 切片大小
  CHUNK_THRESHOLD: 5 * 1024 * 1024, // 5MB 以上才切片
  MAX_CONCURRENT: 3, // 最大同时上传数
  RETRY_TIMES: 3, // 重试次数
  SERVER_URL: 'http://10.0.2.2:3000', // Android模拟器专用IP，用于文件上传
};

// 文件上传状态
export interface UploadFile {
  id: string;
  file: {
    uri: string;
    name: string;
    size: number;
    type: string;
  };
  status: 'pending' | 'uploading' | 'paused' | 'completed' | 'failed';
  progress: number;
  chunks: ChunkInfo[];
  uploadedChunks: Set<number>;
  retryCount: number;
  useChunking: boolean; // 是否使用切片上传
}

// 切片信息
interface ChunkInfo {
  index: number;
  start: number;
  end: number;
  size: number;
  hash: string;
}

// 上传管理器
class UploadManager {
  private uploads: Map<string, UploadFile> = new Map();
  private isProcessing = false;
  private serverUrl: string = '';
  private isInitialized = false; // 添加初始化状态标志

  constructor() {
    this.initializeServer();
  }

  private async initializeServer() {
    try {
      this.serverUrl = await getWorkingServer();
      UPLOAD_CONFIG.SERVER_URL = this.serverUrl;
      this.isInitialized = true; // 标记为已初始化
      console.log(`🚀 上传管理器初始化完成，使用服务器: ${this.serverUrl}`);
    } catch (error) {
      console.error('❌ 无法找到可用的服务器:', error);
      // 使用默认地址作为后备
      this.serverUrl = 'http://10.0.2.2:3000';
      UPLOAD_CONFIG.SERVER_URL = this.serverUrl;
      this.isInitialized = true; // 即使失败也标记为已初始化
    }
  }

  // 等待初始化完成
  private async waitForInitialization(): Promise<void> {
    if (this.isInitialized) return;
    
    let attempts = 0;
    const maxAttempts = 50; // 最多等待5秒
    
    while (!this.isInitialized && attempts < maxAttempts) {
      await new Promise<void>(resolve => setTimeout(() => resolve(), 100));
      attempts++;
    }
    
    if (!this.isInitialized) {
      throw new Error('上传管理器初始化超时');
    }
  }

  // 添加文件到上传队列
  async addFile(file: { uri: string; name: string; size: number; type: string }): Promise<string> {
    // 等待初始化完成
    await this.waitForInitialization();
    
    const fileId = `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    
    // 计算是否需要切片
    const useChunking = file.size > UPLOAD_CONFIG.CHUNK_THRESHOLD;
    const chunks = useChunking ? this.calculateChunks(file.size) : [this.createVirtualChunk(file.size)];
    
    const uploadFile: UploadFile = {
      id: fileId,
      file,
      status: 'pending',
      progress: 0,
      chunks,
      uploadedChunks: new Set(),
      retryCount: 0,
      useChunking,
    };

    this.uploads.set(fileId, uploadFile);
    console.log(`📁 文件已添加到上传队列: ${file.name}, ID: ${fileId}`);
    
    // 开始处理队列
    this.processQueue();
    
    return fileId;
  }

  // 处理上传队列
  private async processQueue() {
    if (this.isProcessing) {
      return;
    }
    this.isProcessing = true;

    const pendingFiles = Array.from(this.uploads.values()).filter(f => f.status === 'pending');
    const activeCount = this.uploads.size;
    
    if (activeCount >= UPLOAD_CONFIG.MAX_CONCURRENT || pendingFiles.length === 0) {
      this.isProcessing = false;
      return;
    }

    const fileToUpload = pendingFiles[0];
    fileToUpload.status = 'uploading';
    
    try {
      await this.uploadFile(fileToUpload);
    } catch (error) {
      console.error(`文件上传失败: ${fileToUpload.file.name}`, error);
      fileToUpload.status = 'failed';
    } finally {
      this.isProcessing = false;
      this.processQueue(); // 继续处理下一个文件
    }
  }

  // 上传文件
  private async uploadFile(uploadFile: UploadFile): Promise<void> {
    const { file, chunks, useChunking } = uploadFile;
    
    try {
      // 检查文件是否已存在
      const fileExists = await this.checkFileExists(file);
      if (fileExists.exists) {
        uploadFile.status = 'completed';
        uploadFile.progress = 100;
        console.log(`✅ 文件已存在，跳过上传: ${file.name}`);
        return;
      }

      // 检查是否有未完成的上传
      if (fileExists.hasIncomplete && fileExists.uploadedChunks) {
        uploadFile.uploadedChunks = new Set(fileExists.uploadedChunks);
        uploadFile.progress = (uploadFile.uploadedChunks.size / chunks.length) * 100;
        console.log(`🔄 发现未完成的上传，继续上传: ${file.name}`);
      }

      if (useChunking) {
        // 大文件使用切片上传
        console.log(`📦 大文件 ${file.name} 使用切片上传，共 ${chunks.length} 个切片`);
        await this.uploadFileInChunks(uploadFile);
      } else {
        // 小文件直接上传
        console.log(`📤 小文件 ${file.name} 直接上传`);
        await this.uploadFileDirectly(uploadFile);
      }

      // 确保状态正确更新
      uploadFile.status = 'completed';
      uploadFile.progress = 100;
      console.log(`✅ 文件上传完成: ${file.name}`);
      
    } catch (error) {
      console.error(`文件上传失败: ${file.name}`, error);
      uploadFile.status = 'failed';
      uploadFile.progress = 0;
      throw error;
    }
  }

  // 切片上传
  private async uploadFileInChunks(uploadFile: UploadFile): Promise<void> {
    const { file, chunks } = uploadFile;
    
    // 上传所有切片
    for (const chunk of chunks) {
      if (uploadFile.uploadedChunks.has(chunk.index)) {
        continue; // 跳过已上传的切片
      }

      try {
        await this.uploadChunk(uploadFile, chunk.index, await this.createChunkData(file.uri, chunk));
        uploadFile.uploadedChunks.add(chunk.index);
        
        // 更新进度
        const progress = Math.round((uploadFile.uploadedChunks.size / chunks.length) * 100);
        uploadFile.progress = progress;
        console.log(`📊 切片上传进度: ${progress}% (${uploadFile.uploadedChunks.size}/${chunks.length})`);
        
      } catch (error) {
        console.error(`切片上传失败: ${chunk.index}`, error);
        
        // 重试机制
        if (uploadFile.retryCount < UPLOAD_CONFIG.RETRY_TIMES) {
          uploadFile.retryCount++;
          console.log(`重试切片 ${chunk.index}，第 ${uploadFile.retryCount} 次`);
          await this.uploadChunk(uploadFile, chunk.index, await this.createChunkData(file.uri, chunk));
          uploadFile.uploadedChunks.add(chunk.index);
          
          // 更新进度
          const progress = Math.round((uploadFile.uploadedChunks.size / chunks.length) * 100);
          uploadFile.progress = progress;
          console.log(`📊 重试后进度: ${progress}% (${uploadFile.uploadedChunks.size}/${chunks.length})`);
          
        } else {
          throw new Error(`切片 ${chunk.index} 上传失败，已重试 ${UPLOAD_CONFIG.RETRY_TIMES} 次`);
        }
      }
    }

    // 合并切片
    console.log(`🔗 开始合并切片: ${file.name}`);
    await this.mergeChunks(uploadFile);
    
    // 确保最终状态正确
    uploadFile.progress = 100;
    uploadFile.status = 'completed';
    console.log(`✅ 切片上传完成: ${file.name}`);
  }

  // 直接上传小文件
  private async uploadFileDirectly(uploadFile: UploadFile): Promise<void> {
    const { file } = uploadFile;
    try {
      const formData = new FormData();
      formData.append('file', { uri: file.uri, type: file.type || 'application/octet-stream', name: file.name } as any);
      formData.append('fileName', file.name);
      formData.append('fileSize', file.size.toString());

      const serverUrl = this.serverUrl || UPLOAD_CONFIG.SERVER_URL;
      console.log(`📤 直接上传到: ${serverUrl}`);
      
      const response = await axios.post(`${serverUrl}/sow/upload/simple`, formData, { 
        timeout: 60000,
        headers: {
          'Content-Type': 'multipart/form-data',
        }
      });
      
      if (!response.data.success) {
        throw new Error(`直接上传失败: ${response.data.message}`);
      }
      
      // 确保状态正确更新
      uploadFile.progress = 100;
      uploadFile.status = 'completed';
      console.log(`✅ 直接上传完成: ${file.name}`);
      
    } catch (error) {
      console.error(`直接上传失败:${file.name}`, error);
      uploadFile.progress = 0;
      uploadFile.status = 'failed';
      throw error;
    }
  }

  // 检查文件是否存在
  private async checkFileExists(file: { name: string; size: number; type: string }): Promise<{
    exists: boolean;
    hasIncomplete?: boolean;
    uploadedChunks?: number[];
    totalChunks?: number;
    fileHash?: string;
  }> {
    try {
      const serverUrl = this.serverUrl || UPLOAD_CONFIG.SERVER_URL;
      const response = await axios.post(`${serverUrl}/sow/upload/check`, {
        fileName: file.name,
        fileSize: file.size,
        fileType: file.type,
      });
      return response.data;
    } catch (error) {
      console.error('检查文件存在失败:', error);
      return { exists: false };
    }
  }

  // 上传切片
  private async uploadChunk(uploadFile: UploadFile, chunkIndex: number, chunkData: Blob): Promise<void> {
    try {
      const formData = new FormData();
      formData.append('file', chunkData);
      formData.append('fileName', uploadFile.file.name);
      formData.append('fileSize', uploadFile.file.size.toString());
      formData.append('chunkIndex', chunkIndex.toString());
      formData.append('chunkSize', uploadFile.chunks[chunkIndex].size.toString());
      formData.append('totalChunks', uploadFile.chunks.length.toString());
      formData.append('chunkHash', uploadFile.chunks[chunkIndex].hash);

      const serverUrl = this.serverUrl || UPLOAD_CONFIG.SERVER_URL;
      const response = await axios.post(`${serverUrl}/sow/upload/chunk`, formData, {
        timeout: 60000,
        headers: {
          'Content-Type': 'multipart/form-data',
        }
      });

      if (!response.data.success) {
        throw new Error(`切片上传失败: ${response.data.message}`);
      }
    } catch (error) {
      console.error(`切片 ${chunkIndex} 上传失败:`, error);
      throw error;
    }
  }

  // 创建切片数据
  private async createChunkData(uri: string, chunk: ChunkInfo): Promise<Blob> {
    // 这里需要根据实际的文件读取方式来实现
    // 对于React Native，可能需要使用react-native-fs或其他库
    // 暂时返回一个模拟的Blob
    return new Blob([`chunk_${chunk.index}`], { 
      type: 'application/octet-stream',
      lastModified: Date.now()
    });
  }

  // 合并切片
  private async mergeChunks(uploadFile: UploadFile): Promise<void> {
    try {
      const { file, chunks } = uploadFile;
      const chunkHashes = chunks.map(chunk => chunk.hash);

      const serverUrl = this.serverUrl || UPLOAD_CONFIG.SERVER_URL;
      const response = await axios.post(`${serverUrl}/sow/upload/merge`, {
        fileName: file.name,
        fileSize: file.size,
        fileType: file.type,
        totalChunks: chunks.length,
        chunkHashes,
      });

      if (!response.data.success) {
        throw new Error(`切片合并失败: ${response.data.message}`);
      }
    } catch (error) {
      console.error('切片合并失败:', error);
      throw error;
    }
  }

  // 暂停上传
  pauseUpload(fileId: string) {
    const uploadFile = this.uploads.get(fileId);
    if (uploadFile && uploadFile.status === 'uploading') {
      uploadFile.status = 'paused';
      // AbortController is not directly managed here as it's not a global instance
      // The axios interceptor or a custom AbortController would be needed for this
    }
  }

  // 恢复上传
  resumeUpload(fileId: string) {
    const uploadFile = this.uploads.get(fileId);
    if (uploadFile && uploadFile.status === 'paused') {
      uploadFile.status = 'pending';
      this.processQueue();
    }
  }

  // 取消上传
  cancelUpload(fileId: string) {
    const uploadFile = this.uploads.get(fileId);
    if (uploadFile) {
      uploadFile.status = 'failed';
      // AbortController is not directly managed here
    }
  }

  // 获取上传状态
  getUploadStatus(fileId: string): UploadFile | undefined {
    return this.uploads.get(fileId);
  }

  // 获取所有上传状态
  getAllUploads(): UploadFile[] {
    return Array.from(this.uploads.values());
  }

  // 清理已完成的上传
  cleanup() {
    this.uploads.forEach(uploadFile => {
      if (uploadFile.status === 'completed') {
        this.uploads.delete(uploadFile.id);
      }
    });
  }

  // 计算切片信息
  private calculateChunks(fileSize: number): ChunkInfo[] {
    const chunks: ChunkInfo[] = [];
    const totalChunks = Math.ceil(fileSize / UPLOAD_CONFIG.CHUNK_SIZE);

    for (let i = 0; i < totalChunks; i++) {
      const start = i * UPLOAD_CONFIG.CHUNK_SIZE;
      const end = Math.min(start + UPLOAD_CONFIG.CHUNK_SIZE, fileSize);
      const size = end - start;
      
      chunks.push({
        index: i,
        start,
        end,
        size,
        hash: `chunk_${i}_${size}`,
      });
    }
    return chunks;
  }

  // 创建虚拟切片
  private createVirtualChunk(size: number): ChunkInfo {
    return {
      index: 0,
      start: 0,
      end: size,
      size,
      hash: `virtual_chunk_${size}`,
    };
  }
}

// 创建全局上传管理器实例
export const uploadManager = new UploadManager();

// 导出便捷的上传函数
export const uploadFileWithChunk = async ({
  file,
  onProgress,
}: {
  file: { uri: string; name: string; size: number; type: string };
  onProgress?: (percent: number) => void;
}) => {
  try {
    console.log('🚀 开始上传文件:', file.name);
    
    const fileId = await uploadManager.addFile(file);
    console.log('📋 文件已添加到队列，ID:', fileId);

    // 创建一个简单的进度模拟器，因为实际上传可能不会立即开始
    let simulatedProgress = 0;
    const progressInterval = setInterval(() => {
      if (simulatedProgress < 90) {
        simulatedProgress += Math.random() * 10;
        onProgress?.(Math.min(simulatedProgress, 90));
      }
    }, 500);
    
    // 监听上传进度
    const checkProgress = async (): Promise<{ success: boolean; message: string; data: any }> => {
      try {
        const status = uploadManager.getUploadStatus(fileId);
        if (status) {
          console.log('📊 上传状态:', status.status, '进度:', status.progress);
    
          if (status.status === 'completed') {
            clearInterval(progressInterval);
            onProgress?.(100);
            return { success: true, message: '文件上传成功', data: status };
          } else if (status.status === 'failed') {
            clearInterval(progressInterval);
            return { success: false, message: '文件上传失败', data: status };
          } else if (status.status === 'uploading' || status.status === 'pending') {
            // 继续检查，但限制检查次数
            return new Promise((resolve) => {
              setTimeout(async () => {
                const result = await checkProgress();
                resolve(result);
              }, 1000);
            });
          }
        }
        
        // 如果状态未知，继续检查
        return new Promise((resolve) => {
          setTimeout(async () => {
            const result = await checkProgress();
            resolve(result);
          }, 1000);
        });
        
      } catch (error) {
        console.error('❌ 检查进度失败:', error);
        clearInterval(progressInterval);
        return { success: false, message: '检查进度失败', data: null };
      }
    };
    
    // 开始检查进度
    const result = await checkProgress();
    
    // 如果立即有结果，返回
    if (result.success !== undefined) {
      return result;
    }
    
    // 否则返回成功消息，表示文件已加入队列
    return { success: true, message: '文件已加入上传队列', data: { fileId } };
    
  } catch (error) {
    console.error('❌ 上传文件失败:', error);
    return { success: false, message: `上传失败: ${error}`, data: null };
  }
};

export const uploadFileSimple = uploadFileWithChunk;
export const uploadFileUltraSimple = uploadFileWithChunk;

export default { uploadFileWithChunk, uploadFileSimple, uploadFileUltraSimple, uploadManager }; 